package mylog

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"time"

	"github.com/gin-gonic/gin"
)

// 自定义日志中间件
func Logger() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 开始时间
		start := time.Now()

		// 处理请求
		c.Next()

		// 结束时间
		end := time.Now()
		latency := end.Sub(start)

		// 日志内容
		log := fmt.Sprintf("%s - [%s] \"%s %s %s %d %v \"%s\" %s\"\n",
			c.ClientIP(),                      // 客户端IP
			end.Format("2006-01-02 15:04:05"), //设置日志打印的时间
			c.Request.Method,                  //获取请求方式
			c.Request.URL.Path,                //获取请求路径
			c.Request.Proto,                   //获取请求协议
			c.Writer.Status(),                 //获取响应状态码
			latency,                           //请求耗时
			c.Request.UserAgent(),             //获取客户端的UserAgent
			c.Errors.ByType(gin.ErrorTypePrivate).String(),
		)

		// 写入日志文件
		writeLog(log)
	}
}

// 写入日志文件
func writeLog(content string) {
	// 创建日志目录
	logDir := "./logs"
	if _, err := os.Stat(logDir); os.IsNotExist(err) {
		os.MkdirAll(logDir, 0755)
	}

	// 按日期生成日志文件名
	today := time.Now().Format("2006-01-02")
	logFile := filepath.Join(logDir, today+".log")

	// 打开文件，如果不存在则创建，追加写入
	file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		fmt.Printf("打开日志文件失败: %v\n", err)
		return
	}
	defer file.Close()

	// 写入日志
	_, err = io.WriteString(file, content)
	if err != nil {
		fmt.Printf("写入日志失败: %v\n", err)
	}
}

// 定期清理日志文件
func startLogCleanup() {
	ticker := time.NewTicker(24 * time.Hour) // 每天检查一次
	go func() {
		for range ticker.C {
			cleanupOldLogs()
		}
	}()
}

// 清理旧日志文件
func cleanupOldLogs() {
	logDir := "./logs"
	retentionDays := 30 // 保留30天的日志

	files, err := os.ReadDir(logDir)
	if err != nil {
		fmt.Printf("读取日志目录失败: %v\n", err)
		return
	}

	cutoffTime := time.Now().AddDate(0, 0, -retentionDays)

	for _, file := range files {
		if file.IsDir() {
			continue
		}

		// 解析文件名中的日期
		filename := file.Name()
		if len(filename) < 10 {
			continue
		}

		dateStr := filename[:10]
		fileTime, err := time.Parse("2006-01-02", dateStr)
		if err != nil {
			continue
		}

		// 删除过期文件
		if fileTime.Before(cutoffTime) {
			filePath := filepath.Join(logDir, filename)
			err := os.Remove(filePath)
			if err != nil {
				fmt.Printf("删除日志文件失败: %s, error: %v\n", filename, err)
			} else {
				fmt.Printf("已删除过期日志文件: %s\n", filename)
			}
		}
	}
}
